---
title: Variants | gluestack-style
description: gluestack-style allows you to easily create different variations of a component with different styles for more flexibility and reusability of components.
---

import { Canvas, Meta, Story } from '@storybook/addon-docs';

<Meta title="styled/api/Variants" />

import { styled, StyledProvider } from '@gluestack-style/react';
import { Pressable, Text } from 'react-native';
import { Button, AppProvider, CodePreview } from '@gluestack/design-system';
import { config } from './config';
import { useState } from 'react';

# Variants

gluestack-style allows you to easily create different variations of a component with different styles.

**Using variant props in a UI component library enhances flexibility and reusability of components**.

### Adding Variants

<AppProvider>
  <CodePreview
    metaData={{
      scope: {
        styled,
        Text,
        Pressable,
        Provider: StyledProvider,
        config,
        useState,
      },
      code: `
        function App() {
          const StyledButtonVariant = styled(Pressable, {
          px: '$3.5',
          py: '$2.5',
          rounded: '$md',
            variants: {
              variant: {
                solid: {
                  bg: '$primary600',
                },
                subtle: {
                  bg: '$primary300'
                }
              },
            },
          });
          const StyledButtonText = styled(
          Text,
          {
            color: '$textDark50',
            fontWeight: '400',
          },
          { ancestorStyle: ['_text'] }
        );
        return (
          <Provider config={config}>
            <StyledButtonVariant {...props}>
              <StyledButtonText>Button</StyledButtonText>
            </StyledButtonVariant>
          </Provider>
        );
      }`,
      argsType: {
        variant: {
          control: 'select',
          options: ['solid', 'subtle'],
          default: 'solid',
        },
      },
    }}
  />
</AppProvider>

### Multiple Variants

<AppProvider>
  <CodePreview
    metaData={{
      scope: {
        styled,
        Text,
        Pressable,
        Provider: StyledProvider,
        config,
        useState,
      },
      code: `
        function App() {
          const StyledButtonVariant = styled(Pressable, {
            p: '$3',
          rounded: '$md',
            variants: {
              variant: {
                solid: {
                  bg: '$primary600',
                },
                subtle: {
                  bg: '$primary200',
                  _text: {
                  color: '$textDark600'
                  }
                },
              },
              size: {
                xs: {
                  px: '$3',
                  py: '$2',
                },
                sm: {
                  px: '$3.5',
                  py: '$2.5',
                },
              },
            },
          }, {
          descendantStyle: ['_text']
        });
          const StyledButtonText = styled(
          Text,
          {
            color: '$textDark50',
            fontWeight: '400',
          },
          { ancestorStyle: ['_text'] }
        );
        return (
          <Provider config={config}>
            <StyledButtonVariant {...props}>
              <StyledButtonText>Button</StyledButtonText>
            </StyledButtonVariant>
          </Provider>
        );
      }`,
      argsType: {
        variant: {
          control: 'select',
          options: ['solid', 'subtle'],
          default: 'solid',
        },
        size: {
          control: 'select',
          options: ['xs', 'sm'],
          default: 'xs',
        },
      },
    }}
  />
</AppProvider>

### Boolean Variants

<AppProvider>
  <CodePreview
    metaData={{
      scope: {
        styled,
        Text,
        Pressable,
        Provider: StyledProvider,
        config,
        useState,
      },
      code: `
        function App() {
        const StyledButtonVariant = styled(Pressable, {
          px: '$3.5',
          py: '$2.5',
          rounded: '$md',
          variants: {
            variant: {
              solid: {
                bg: '$primary600',
              },
              subtle: {
                bg: '$primary400',
              },
            },
            outlined: {
              true: {
                borderColor: '$primary800',
                borderWidth: '$1',
                bg: 'transparent'
              },
            },
          },
        });
        const StyledButtonText = styled(
          Text,
          {
            color: '$textDark50',
            fontWeight: '400',
          },
          { ancestorStyle: ['_text'] }
        );
        return (
          <Provider config={config}>
            <StyledButtonVariant {...props}>
              <StyledButtonText>Button</StyledButtonText>
            </StyledButtonVariant>
          </Provider>
        );
      }`,
      argsType: {
        variant: {
          control: 'select',
          options: ['solid', 'subtle'],
          default: 'solid',
        },
        outlined: {
          control: 'boolean',
          default: false,
        },
      },
    }}
  />
</AppProvider>

### Compound Variants

The compoundVariants feature enables setting styles for a variant based on a combination of other variants. This allows specifying different styles for a variant, depending on the values of other variants in use.

> **Note:** `compoundVariants` is an array of objects that contain a `value` key and variants. The `value` key accepts the same style object as the sx style.

<AppProvider>
  <CodePreview
    metaData={{
      scope: {
        styled,
        Text,
        Pressable,
        Provider: StyledProvider,
        config,
        useState,
      },
      code: `
        function App() {
        const StyledButtonVariant = styled(Pressable, {
          p: '$3',
          rounded: '$md',
          variants: {
            variant: {
              solid: {
                bg: '$primary600',
              },
              subtle: {
                bg: '$primary200',
                _text: {
                  color: '$textDark600'
                }
              },
            },
            size: {
              xs: {
                px: '$3',
                py: '$2',
              },
              sm: {
                px: '$3.5',
                py: '$2.5',
              },
            },
          },
          compoundVariants: [
            {
              variant: 'solid',
              size: 'sm',
              value: {
                'borderWidth': '$2',
                ':hover': {
                  bg: '$primary700',
                },
              },
            },
          ],
        }, {
          descendantStyle: ['_text']
        });
        const StyledButtonText = styled(
          Text,
          {
            color: '$textDark50',
            fontWeight: '400',
          },
          { ancestorStyle: ['_text'] }
        );
        return (
          <Provider config={config}>
            <StyledButtonVariant {...props} states={{hover: true}}>
              <StyledButtonText>Button</StyledButtonText>
            </StyledButtonVariant>
          </Provider>
        );
      }`,
      argsType: {
        variant: {
          control: 'select',
          options: ['solid', 'subtle'],
          default: 'solid',
        },
        size: {
          control: 'select',
          options: ['xs', 'sm'],
          default: 'sm',
        },
      },
    }}
  />
</AppProvider>
